package com.searchingmodule;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import Neighborhood.Neighborhood;

import com.imagefinder.ImageFinder;
import com.imagefinder.YahooImageFinder;
import com.model.DataModel;
import com.recommender.Recommender;
import com.recommender.SimpleRecommender;
import com.util.XmlResultString;

public class SearchingElement {

	private HashMap<String, String> contextMap;
	//private DataModel datamodel;
	public DataModel datamodel;
	private Neighborhood neighborhood;
	private Recommender recommender;
	private ImageFinder imagefinder;

	public boolean isUserBased = false;
	private long userID = Integer.MIN_VALUE;
	private String keyword = null;
	private Integer currentSearchEngineIndex=new Integer(-1);
	private int imageURLIndex=-1;
	private String[] imageURLs = new String[20];
	private String[] srcImageUrls=new String[20];
	Map receivedImageResults;

	public void setDataModel(DataModel datamodel) {
		this.datamodel = datamodel;
	}

	public void setNeighborhood(Neighborhood neighborhood) {
		this.neighborhood = neighborhood;
	}

	public void setRecommender(Recommender recommender) {
		this.recommender = recommender;
	}

	public void setImageFinder(ImageFinder imagefinder) {
		this.imagefinder = imagefinder;
	}

	public void setUserID(long userID) {
		this.userID = userID;
	}

	public void setKeyword(String keyword) {
		this.keyword = keyword;
	}
//Get recommendations from the not user based algorithms
	public String getRecommendedImages(String keyword,
			HashMap<String, String> contextMap, int GCount) throws Exception{
		LinkedHashMap<String, String> tempImageResults;
		this.contextMap = contextMap;

		String[] keywordArray = keyword.split(" ");

		String[] array = new String[20];
		ArrayList<String> urls = new ArrayList<String>();
		System.out.println("In recommended imgs");

		LinkedHashMap<String, Double> finalImageResults = new LinkedHashMap<String, Double>();
		
		
		
		ArrayList<String> recommendedImagsSrcUrls=new ArrayList<String>();
		ArrayList<String> googleSrcImages=new ArrayList<String>();
		ArrayList<String> googleImageResults = new ArrayList<String>();
		
		
		
		
		
//Check for the request nuber and recommend according to that 
		if (GCount == 0) {
			receivedImageResults = new HashMap<Integer, Double>();

			receivedImageResults = recommender.getRecommendations(contextMap,
					keyword, Integer.MIN_VALUE, datamodel, neighborhood);

			if (keywordArray.length >= 2) {//If multiple key words recommend according to that
				for (String string : keywordArray) {

					Map<Integer, Double> newMap = new HashMap<Integer, Double>();
					newMap = recommender
							.getRecommendations(contextMap, keyword,
									Integer.MIN_VALUE, datamodel, neighborhood);

					Set set = newMap.entrySet();
					Iterator i = set.iterator();
					int count = 0;
					while (i.hasNext()) {

						Map.Entry<Integer, Double> me = (Map.Entry<Integer, Double>) i
								.next();
						receivedImageResults.put(me.getKey(), me.getValue());
					}

				}
			}

		}

		
		
		
		
Iterator iterator = receivedImageResults.keySet().iterator();
int imageID;
for(int k=0;k<GCount*20;k++){
	if(iterator.hasNext()){
		imageID=(Integer)iterator.next();
	}
}
		
		// Getting a total of 20 images 
		
		
		if ((receivedImageResults.size() >= (GCount + 1) * 20)) {

			for (int i = GCount * 20; i < ((GCount + 1) * 20); i++) {
				imageID = (Integer) iterator.next();

				try {
					finalImageResults.put(datamodel.getImageURL(imageID),
							(Double) receivedImageResults.get(imageID));
					recommendedImagsSrcUrls.add(datamodel.getSrcImageURL(imageID));
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

		} else if (receivedImageResults.size() > 0) {
			for (int i = GCount * 20; i < receivedImageResults.size(); i++) {
				imageID = (Integer) iterator.next();
				System.out.println("Image ID=" + imageID);
				try {
					finalImageResults.put(datamodel.getImageURL(imageID),
							(Double) receivedImageResults.get(imageID));
					recommendedImagsSrcUrls.add(datamodel.getSrcImageURL(imageID));
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		
		
		
		
		
		
		LinkedHashMap imageResultsMap=finalImageResults;
		
		int currentRecommendedImgNumber=imageResultsMap.size();
		int requiredImages=20-currentRecommendedImgNumber;
		keyword = keyword.trim().replace(" ", "+");
		if(currentSearchEngineIndex==-1){
			tempImageResults = imagefinder.getResults(keyword, currentSearchEngineIndex+1);
			currentSearchEngineIndex=new Integer(currentSearchEngineIndex+1);
			System.out.println("------------------------------------------------");
			Iterator itr=tempImageResults.keySet().iterator();
			int i=0;
			while(itr.hasNext()){
				String tempimage=itr.next().toString();
				System.out.println(tempimage);
				this.imageURLs[i]=tempimage;
				this.srcImageUrls[i]=tempImageResults.get(tempimage);
				i=i+1;
			}
			System.out.println("-----------------------------------------------------");
			imageURLIndex=0;
		}
		if(requiredImages>0){
			if(requiredImages>(20-imageURLIndex)){
			for(int i=imageURLIndex;i<20;i++){
				googleImageResults.add(imageURLs[i]);
				googleSrcImages.add(srcImageUrls[i]);
			}
			tempImageResults = imagefinder.getResults(keyword, currentSearchEngineIndex+1);
			currentSearchEngineIndex=new Integer(currentSearchEngineIndex+1);
			System.out.println("-----------------------------------------------------");
			Iterator itr=tempImageResults.keySet().iterator();
			int i=0;
			while(itr.hasNext()){
				String tempimage=itr.next().toString();
				System.out.println(tempimage);
				this.imageURLs[i]=tempimage;
				this.srcImageUrls[i]=tempImageResults.get(tempimage);
				i=i+1;
			}

			System.out.println("-----------------------------------------------------");
			
			
			
			int tempRequiredImages=requiredImages-(20-imageURLIndex);
			imageURLIndex=0;
			int j;
			for(j=0;j<tempRequiredImages;j++){
				googleImageResults.add(this.imageURLs[j]);
				googleSrcImages.add(this.srcImageUrls[j]);
			}
			imageURLIndex=j;
			
			}else{
				
				if(requiredImages<(imageURLs.length-imageURLIndex)){
				
					int i=0;
					for(i=imageURLIndex;i<imageURLIndex+requiredImages;i++){
						googleImageResults.add(imageURLs[i]);
						googleSrcImages.add(srcImageUrls[i]);
						
					}
					imageURLIndex=i;
				}else{
					int i=0;
					for(i=imageURLIndex;i<imageURLIndex+requiredImages;i++){
						googleImageResults.add(imageURLs[i]);
						googleSrcImages.add(srcImageUrls[i]);
					}
						//imageURLIndex=i;						
						tempImageResults = imagefinder.getResults(keyword, currentSearchEngineIndex+1);
						currentSearchEngineIndex=new Integer(currentSearchEngineIndex+1);
						System.out.println("-----------------------------------------------------");
						Iterator itr=tempImageResults.keySet().iterator();
						int k=0;
						while(itr.hasNext()){
							String tempimage=itr.next().toString();
							System.out.println(tempimage);
							this.imageURLs[k]=tempimage;
							this.srcImageUrls[k]=tempImageResults.get(tempimage);
							k=k+1;
						}

						System.out.println("-----------------------------------------------------");
						imageURLIndex=0;
					
					
					
					
				}
				
				
			}
		}

		
		
		
		
		
//create the xml string from the result
		String xml = new XmlResultString().createXmlResult(imageResultsMap,
				googleImageResults, googleSrcImages,recommendedImagsSrcUrls);
		System.out.println(xml);

		return xml;

	}

	//for the user based recommendations
	public String geRecommendedImages(String keyword, long userID,
			HashMap<String, String> contextMap, int GCount) throws Exception{
		LinkedHashMap<String, String> tempImageResults;
		this.contextMap = contextMap;
		
		String[] keywordArray = keyword.split(" ");


		String[] array = new String[20];
		//String[] imageURLs = new String[20];
		ArrayList<String> urls = new ArrayList<String>();


		LinkedHashMap<String, Double> finalImageResults = new LinkedHashMap<String, Double>();
		ArrayList<String> recommendedImagsSrcUrls=new ArrayList<String>();
		ArrayList<String> googleImageResults = new ArrayList<String>();
		ArrayList<String> googleSrcImages=new ArrayList<String>();

		if (GCount == 0) {
			receivedImageResults = new TreeMap<Integer, Double>();

			receivedImageResults = recommender.getRecommendations(contextMap,
					keyword, userID, datamodel, neighborhood);

			if (keywordArray.length >= 2) {
				for (String string : keywordArray) {

					Map<Integer, Double> newMap = new HashMap<Integer, Double>();
					newMap = recommender
							.getRecommendations(contextMap, string,
									userID, datamodel, neighborhood);

					Set set = newMap.entrySet();
					Iterator i = set.iterator();
					int count = 0;
					while (i.hasNext()) {

						Map.Entry<Integer, Double> me = (Map.Entry<Integer, Double>) i
								.next();
						receivedImageResults.put(me.getKey(), me.getValue());
					}

				}
			}

		}
		Iterator iterator = receivedImageResults.keySet().iterator();
		
		
		int imageID;
		for(int k=0;k<GCount*20;k++){
			if(iterator.hasNext()){
				imageID=(Integer)iterator.next();
			}
		}

		
		if ((receivedImageResults.size() >= (GCount + 1) * 20)) {

			for (int i = GCount * 20; i < ((GCount + 1) * 20); i++) {
				imageID = (Integer) iterator.next();

				try {
					finalImageResults.put(datamodel.getImageURL(imageID),
							(Double) receivedImageResults.get(imageID));
					recommendedImagsSrcUrls.add(datamodel.getSrcImageURL(imageID));
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

		} else if (receivedImageResults.size() > 0) {
			for (int i = GCount * 20; i < receivedImageResults.size(); i++) {
				imageID = (Integer) iterator.next();
				System.out.println("Image ID=" + imageID);
				try {
					finalImageResults.put(datamodel.getImageURL(imageID),
							(Double) receivedImageResults.get(imageID));
					recommendedImagsSrcUrls.add(datamodel.getSrcImageURL(imageID));
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

		
		
		
		

		LinkedHashMap imageResultsMap=finalImageResults;
		
		int currentRecommendedImgNumber=imageResultsMap.size();
		int requiredImages=20-currentRecommendedImgNumber;
		keyword = keyword.trim().replace(" ", "+");
		if(currentSearchEngineIndex==-1){
			tempImageResults = imagefinder.getResults(keyword, currentSearchEngineIndex+1);
			currentSearchEngineIndex=new Integer(currentSearchEngineIndex+1);
			System.out.println("------------------------------------------------");
			Iterator itr=tempImageResults.keySet().iterator();
			int i=0;
			while(itr.hasNext()){
				String tempimage=itr.next().toString();
				System.out.println(tempimage);
				this.imageURLs[i]=tempimage;
				this.srcImageUrls[i]=tempImageResults.get(tempimage);
				i=i+1;
			}
			System.out.println("-----------------------------------------------------");
			imageURLIndex=0;
		}
		if(requiredImages>0){
			if(requiredImages>(20-imageURLIndex)){
			for(int i=imageURLIndex;i<20;i++){
				googleImageResults.add(imageURLs[i]);
				googleSrcImages.add(srcImageUrls[i]);
			}
			tempImageResults = imagefinder.getResults(keyword, currentSearchEngineIndex+1);
			currentSearchEngineIndex=new Integer(currentSearchEngineIndex+1);
			System.out.println("-----------------------------------------------------");
			Iterator itr=tempImageResults.keySet().iterator();
			int i=0;
			while(itr.hasNext()){
				String tempimage=itr.next().toString();
				System.out.println(tempimage);
				this.imageURLs[i]=tempimage;
				this.srcImageUrls[i]=tempImageResults.get(tempimage);
				i=i+1;
			}

			System.out.println("-----------------------------------------------------");
			
			
			
			int tempRequiredImages=requiredImages-(20-imageURLIndex);
			imageURLIndex=0;
			int j;
			for(j=0;j<tempRequiredImages;j++){
				googleImageResults.add(this.imageURLs[j]);
				googleSrcImages.add(this.srcImageUrls[j]);
			}
			imageURLIndex=j;
			
			}else{
				
				if(requiredImages<(imageURLs.length-imageURLIndex)){
				
					int i=0;
					for(i=imageURLIndex;i<imageURLIndex+requiredImages;i++){
						googleImageResults.add(imageURLs[i]);
						googleSrcImages.add(srcImageUrls[i]);
						
					}
					imageURLIndex=i;
				}else{
					int i=0;
					for(i=imageURLIndex;i<imageURLIndex+requiredImages;i++){
						googleImageResults.add(imageURLs[i]);
						googleSrcImages.add(srcImageUrls[i]);
					}
											
						tempImageResults = imagefinder.getResults(keyword, currentSearchEngineIndex+1);
						currentSearchEngineIndex=new Integer(currentSearchEngineIndex+1);
						System.out.println("-----------------------------------------------------");
						Iterator itr=tempImageResults.keySet().iterator();
						int k=0;
						while(itr.hasNext()){
							String tempimage=itr.next().toString();
							System.out.println(tempimage);
							this.imageURLs[k]=tempimage;
							this.srcImageUrls[k]=tempImageResults.get(tempimage);
							k=k+1;
						}

						System.out.println("-----------------------------------------------------");
						imageURLIndex=0;
					
					
					
					
				}
				
				
			}
			/*if(googleImageResults.size()<requiredImages){
				imageURLs = imagefinder.getResults(keyword, GCount);
			}*/
		}

				
		

		/*for (int i = 0; i < 10; i++) {

			googleImageResults.add(imageURLs[i]);

		}
*/
		String xml = new XmlResultString().createXmlResult(imageResultsMap,
				googleImageResults, googleSrcImages,recommendedImagsSrcUrls);
		System.out.println(xml);

		return xml;

	}

	public int saveUserFeedback(String url) {
		try {
			if (isUserBased) {
				datamodel.saveUserFeedback(contextMap, userID, keyword, url,
						Long.MIN_VALUE);
			} else {
				datamodel.saveUserFeedback(contextMap, Integer.MIN_VALUE,
						keyword, url, Long.MIN_VALUE);
			}

			return 1;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return 0;
		}

	}

}
